/*
Copyright (c) 2012, 2013 Regents of the University of California
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 
are met:

 - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the
   distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
OF THE POSSIBILITY OF SUCH DAMAGE.
*/


//analysisRadio and mapColumn are god awful and should be rewritten! (my excuse is that things kept getting changed...)
function mapColumn(analysisType){
	//switch between the different chart types
	$('#resampleTime').removeAttr('disabled')
	$('#resample_select').removeAttr('disabled')
	if ($('#ctRadioMap').is(':checked') || $('#ctRadioMapTop').is(':checked') || $('#ctRadioPlenumMap').is(':checked')){
    	is_map = true  //this is a dumb variable that I should get rid of--it is used for determining the type of chart image (map and flot vs highcharts) also, while not initially, it now seems to be serving the same function as chart_engine
    	$('#treeSelections').hide()
    	$('#ieqSaveForm').hide()
    	$('#avgDay').attr('disabled',true).attr('checked',false)
		if ($('#ctRadioMapTop').is(':checked')){
			$('#analysisOptionsE').hide()
		}
		else{
			$('#analysisOptionsE').show()
		}
		$.ajax({
			type: "GET",
			url: "/pmp/utils/",
			data: {'utilType': 'flr_model', 'projectId':sessvars.sessionObj['projectId']},
			success: function(data){
				$('#analysisOptionsFlr').html(data)
			},
			async: false
		});
		$('#analysisOptionsFlr').show()
	}
	else {
		is_map = false
		buildTree(analysisType, 'none');
		$('#analysisOptionsFlr').hide()
		$('#avgDay').removeAttr('disabled')
		if ($('#ctRadioTimeSeriesTop').is(':checked')){
			$('#analysisOptionsE').hide()
			$('#treeSelections').hide()
		}
		else{
			$('#analysisOptionsE').show()
			$('#treeSelections').show()
		}
		if (analysisType != 'comfort' && analysisType != 'plenum'){
			$('#avgDay').attr('disabled',true).attr('checked',false)
			$.ajax({
				type: "GET",
				url: "/pmp/utils/",
				data: {'utilType': 'ieq_model', 'projectId': sessvars.sessionObj['projectId']},
				success: function(data){
					$('#analysisOptionsIEQ').html(data)
					$('#ieqSaveForm').show()
				},
				async: false
			});
			$('#analysisOptionsIEQ').show()
		}
	}
}

function analysisRadio(projectName, refresh){
	is_map = false //set this global variable in order to determine whether or not we are doing a map
	if (typeof refresh == 'undefined'){
		var refresh = false
	}
	cleanChart();
	getTimeRange();
	//setpoint analysis
	if (document.getElementById("analysisRadio1").checked){
		is_map = true
		$('#analysisOptionsE').html('')
		$('#avgDay').attr('disabled',true).attr('checked',false)
		$('#analysisOptionsIEQ').hide()
		$('#analysisOptionsFlr').hide()
		$('#setpointHeading').show()
		$('#smoothGroup').show()
		$('#hooDiv').show()
		$('#spatialHeading').html('<a style="font-size: 12px; font-weight: bold" class="accordion-toggle" data-toggle="collapse" href="#collapseStreams">Define Setpoint and Point Pairs</a>')
		$('#analysisOptions').html('')
		$('#maintain_zoom').attr('disabled', true)
		analysisType = 'setpoint'
		var stratDevice = 'none'
		updateTree(projectName); //update BMS tree--function from bmsTagtree.js
		buildSetpointTree();
		var projectId = sessvars.sessionObj['projectId']
		$.ajax({
			type: "POST",
			url: '/pmp/comfort/',
			data: {'projectIdChange': projectId},
			success: function(data){
				$('#setpointHeading').html(data)
			}
		});
		}
	//comfort analysis ICMS
	else if (document.getElementById("analysisRadio2").checked){
		$('#avgDay').removeAttr('disabled')
		$('#analysisOptionsIEQ').hide()
		$('#analysisOptionsFlr').hide()
		$('#setpointHeading').hide()
		$('#smoothGroup').show()
		$('#hooDiv').show()
		$('#spatialHeading').html('<a style="font-size: 12px; font-weight: bold" class="accordion-toggle" data-toggle="collapse" href="#collapseStreams">Spatial Filtering</a>')
		$('#maintain_zoom').removeAttr('disabled')	
		analysisType = 'comfort'
		buildTree(analysisType, 'none');
		if (!refresh){
			$('#analysisOptions').html('<h6>Options</h6><div class="controls" id="ctRadioDiv"><label class="radio"><input type="radio" name="ctRadio" id="ctRadioComfortTool" checked>Send data to CBE comfort tool (must allow popups)</label><label class="radio"><input type="radio" name="ctRadio" id="ctRadioMapTop">Map chart (operative temperature)</label><label class="radio"><input type="radio" name="ctRadio" id="ctRadioTimeSeriesTop">Time series chart (operative temperature)</label></div>')
			$('#analysisOptionsE').html('<form class="form-inline" style="margin-bottom: 5px"><label class="control-label" style="font-size: 11px"><input type="text" class="input-mini" id="met" value="1.1">&nbsp;Metabolic rate&nbsp;</label><label class="control-label" style="font-size: 11px"><input type=\"text\" class="input-mini" id="clo" value="0.8">&nbsp;Clothing level&nbsp;</label>&nbsp;<a id="clo_met_info" href="#"><i class="icon-info-sign"></i></a></form>')
			$('#clo_met_info_dialog').dialog({autoOpen: false})
	    	$("#clo_met_info").click(function(){
	    		$('#clo_met_info_dialog').dialog("open");
	    	})
		}
		mapColumn('comfort')
		$('#ctRadioDiv input:radio').change(function(){
	    	mapColumn('comfort')
		});
		$("#treeSelections").html(
			'<h6>Aggregate spatially and group by symbol</h6>' +
			'<div class="controls"><label class="checkbox"><input type="checkbox" id="aggregate" onclick="javascript: aggregateCheck();">Aggregate</label>' +
			'<div style="margin-left: 15px"><label class="radio"><input id="agg_zone" name="agg" type="radio" value="zone" checked disabled>Zone</label>' +
			'<label class="radio"><input id="agg_o" name="agg" type="radio" value="orientation" disabled>Orientation</label></div>' +
			'</div>')
	}
	//comfort analysis stratification
	else if (document.getElementById("analysisRadio3").checked){
		is_map = true //flot chart type
		$('#analysisOptionsE').html('')
		$('#avgDay').attr('disabled',true).attr('checked',false)
		$('#analysisOptionsFlr').hide()
		$('#analysisOptionsIEQ').hide()
		$('#setpointHeading').hide()
		analysisType = 'stratComfort';
		var stratDevice = 'Cart';
		if (!refresh){
			$('#spatialHeading').html('<a style="font-size: 12px; font-weight: bold" class="accordion-toggle" data-toggle="collapse" href="#collapseStreams">Spatial Filtering</a>')
			$('#analysisOptions').html('<p><h6>Options</h6></p><form class="form-inline" style="margin-bottom: 5px"><label class="control-label" style="font-size: 11px"><input type="text" class="input-mini" id="met" value="1.1">&nbsp;Metabolic rate&nbsp;</label><label class="control-label" style="font-size: 11px"><input type=\"text\" class="input-mini" id="clo" value="0.8">&nbsp;Clothing level&nbsp;</label>&nbsp;<a id="clo_met_info" href="#"><i class="icon-info-sign"></i></a></form><label class="checkbox"><input type="checkbox" id="cartChk" checked="True" onclick="stratDeviceChk();">Cart</label><label class="checkbox"><input type="checkbox" id="fpChk" onclick="stratDeviceChk();">Fixed poles</label></p>')
			$('#clo_met_info_dialog').dialog({autoOpen: false})
	    	$("#clo_met_info").click(function(){
	    		$('#clo_met_info_dialog').dialog("open");
	    	})
		}
		stratDeviceChk();
	}
	//room air stratification
	else if (document.getElementById("analysisRadio4").checked){
		is_map = true //flot chart type
		$('#analysisOptionsE').html('')
		$('#avgDay').attr('disabled',true).attr('checked',false)
		$('#setpointHeading').hide()
		$('#analysisOptionsFlr').hide()
		$('#analysisOptionsIEQ').hide()
		analysisType = 'ras';
		var stratDevice = 'Cart';
		if (!refresh){
			$('#spatialHeading').html('<a style="font-size: 12px; font-weight: bold" class="accordion-toggle" data-toggle="collapse" href="#collapseStreams">Spatial Filtering</a>')
			$('#analysisOptions').html('<p><h6>Options</h6></p><p><label class="checkbox"><input type="checkbox" onclick="stratDeviceChk();" id="cartChk" checked="True">Cart</label><label class="checkbox"><input type="checkbox" id="fpChk" onclick="stratDeviceChk();">Fixed poles</label></p>')
		}
		stratDeviceChk();
	}
	//plenum analysis
	else if (document.getElementById("analysisRadio6").checked){
		is_map = true		
		$('#analysisOptionsE').html('')
		$('#analysisOptionsIEQ').hide()
		$('#setpointHeading').hide()
		var stratDevice = 'none'
		analysisType = 'plenum'
		if (!refresh){
			$('#analysisOptions').html('<h6>Options</h6><div class="controls" id="ctRadioDiv"><label class="radio"><input type="radio" name="ctRadio" id="ctRadioPlenumMap" checked>Map</label><label class="radio"><input type="radio" name="ctRadio" id="ctRadioPlenumBoxplot">Boxplot</label></div>')
			$('#spatialHeading').html('<a style="font-size: 12px; font-weight: bold" class="accordion-toggle" data-toggle="collapse" href="#collapseStreams">Spatial Filtering</a>')
			mapColumn(analysisType)
		}
		$('#ctRadioDiv input:radio').change(function(){
	    	mapColumn(analysisType)
		});
		buildTree(analysisType, stratDevice);
	}
	//performance summary model
	else {
		$('#analysisOptionsE').html('')
		$('#avgDay').attr('disabled',true).attr('checked',false)
		$('#maintain_zoom').attr('disabled', true)
		$('#setpointHeading').hide()
		$('#analysisOptionsFlr').hide()
		$('#smoothGroup').show()
		$('#hooDiv').show()
		analysisType = 'ieq_model'
		var stratDevice = 'none'
		if (!refresh){
			$('#analysisOptions').html('<h6>Options</h6><div class="controls" id="ctRadioDiv"><label class="radio"><input type="radio" name="ctRadio" id="ctRadioStackedBar" checked>Stacked bar chart</label><label class="radio"><input type="radio" name="ctRadio" id="ctRadioMap">Map chart</label></div>')
			$('#analysisOptionsE').html('<form class="form-inline" style="margin-bottom: 5px"><label class="control-label" style="font-size: 11px"><input type="text" class="input-mini" id="met" value="1.1">&nbsp;Metabolic rate&nbsp;</label><label class="control-label" style="font-size: 11px"><input type=\"text\" class="input-mini" id="clo" value="0.8">&nbsp;Clothing level&nbsp;</label>&nbsp;<a id="clo_met_info" href="#"><i class="icon-info-sign"></i></a></form>')
			$('#clo_met_info_dialog').dialog({autoOpen: false})
	    	$("#clo_met_info").click(function(){
	    		$('#clo_met_info_dialog').dialog("open");
	    	})			
		}
		mapColumn(analysisType)
		$('#ctRadioDiv input:radio').change(function(){
	    	mapColumn(analysisType)
		});
		buildTree(analysisType, stratDevice);
		$("#treeSelections").html('')
	}
}

function aggregateCheck() {
	if($('#aggregate').is(':checked')){$('#agg_zone').removeAttr("disabled"); $('#agg_o').removeAttr("disabled");}
	else{$('#agg_zone').attr("disabled", true); $('#agg_o').attr("disabled", true);}
}

function stratDeviceChk(){
	$('#analysisOptionsIEQ').hide()
	$("#treeSelections").html(
	'<h6>Aggregate spatially and group by symbol</h6>' +
	'<div class="controls"><label class="checkbox"><input type="checkbox" id="aggregate" onclick="javascript: aggregateCheck();">Aggregate</label>' +
	'<div style="margin-left: 15px"><label class="radio"><input id="agg_zone" name="agg" type="radio" value="zone" checked disabled>Zone</label>' +
	'<label class="radio"><input id="agg_o" name="agg" type="radio" value="orientation" disabled>Orientation</label></div>' +
	'</div>')
	$('#treeSelections').show()
	$('#smoothGroup').show()
	$('#hooDiv').show()
	$('#maintain_zoom').removeAttr('disabled')
	if (document.getElementById("analysisRadio3").checked){var analysisType = 'stratComfort';}
	else {var analysisType = 'ras';}
	if (document.getElementById('cartChk').checked && document.getElementById('fpChk').checked){
		var stratDevice = 'cart_pole'
		$('#smoothGroup').hide()
		$('#hooDiv').hide()
		}
	else if (document.getElementById('cartChk').checked){
		var stratDevice = 'Cart'
		$('#smoothGroup').hide()
		$('#hooDiv').hide()
		}
	else if (document.getElementById('fpChk').checked){
		var stratDevice = 'Fixed pole'
		$('#treeSelections').hide()
		}
	else {var stratDevice = 'none'}
	buildTree(analysisType, stratDevice);
}

function buildSetpointTree(load, data){
	if ($('#fixed_setpoints').is(':checked') || $('#custom_fixed_setpoints').is(':checked')){
				$('#loadSearchedSetpoints').attr('disabled','disabled')
			}
	if (load == true){
		var jsonData = {  
         	"ajax" : {  
	            "url" : "/pmp/cfload/",  
	            "data" : $('form#configDrop').serializeObject(),
	            "success" : function (){
	            	//value = string($('select#id_for_name').val())
	            var configFileName = $('select#id_for_name').find("option:selected").text()
	            $('#id_form_name').val(configFileName)	
	            },
         	}  
     	}
     }
     else if (load == 'fixed'){
     	var existingJSON = $('#treeSelections').jstree("get_json");
     	var jsonData = {  
	        "data" : [existingJSON[0]],
	    }
     }
     else if (data){
     	var existingJSON = $('#treeSelections').jstree("get_json");
     	if (data[0] == 'points'){
     		if ($('#appendPoints').is(':checked')){
     			var childrenL = existingJSON[0].children.concat(data.slice(1))
     			var non_duplicated = []
     			childrenL = childrenL.sort(function(a,b){
     				return (a.data.localeCompare(b.data));
     			})
     			for (var i=0;i<childrenL.length - 1;i++){
     				var object1 = childrenL[i]
     				var object2 = childrenL[i+1]
     				if (object1.data != object2.data){
     					non_duplicated.push(childrenL[i])
     				}
     			}
     			non_duplicated.push(childrenL[i])
     			childrenL = non_duplicated
     		}
     		else {
     			var childrenL = data.slice(1)
     		}
	     	var jsonData = {  
		        "data" : [{ data: "Zone Points", children: childrenL, state: "open" ,  attr: {id: "id1", rel:"folder", class:"jstree-drop"}},
		         existingJSON[1]],
		    }
	    }
	    else{
	     	if ($('#appendPoints').is(':checked')){
     			var childrenL = existingJSON[1].children.concat(data.slice(1))
     			var non_duplicated = []
     			childrenL = childrenL.sort(function(a,b){
     				return (a.data.localeCompare(b.data));
     			})
     			for (var i=0;i<childrenL.length - 1;i++){
     				var object1 = childrenL[i]
     				var object2 = childrenL[i+1]
     				if (object1.data != object2.data){
     					non_duplicated.push(childrenL[i])
     				}
     			}
     			non_duplicated.push(childrenL[i])
     			childrenL = non_duplicated
     		}
     		else {
     			var childrenL = data.slice(1)
     		}
	     	var jsonData = {  
		        "data" : [existingJSON[0],{ data: "Zone Points", children: childrenL, state: "open" ,  attr: {id: "id1", rel:"folder", class:"jstree-drop"}}
		         ],
		    }
	    }
     }
     //else if (data[0].data = "")
     else {
     	var jsonData = {  
	        "data" : [{ data: "Zone Points", children: [], state: "open" ,  attr: {id: "id1", rel:"folder", class:"jstree-drop"},},
	         { data: "Zone Setpoints", children: [], state: "open", attr: {id: "id2", rel:"folder", class:"jstree-drop"},}],
	    }
     }	
	$("#treeSelections").jstree({ 
		"json_data" :  jsonData,  
 		"types" : {
			"valid_children" : [ "root" ],
			"types" : {
				"root" : {"valid children" : "folder"},
				"default" : {},
				"folder" : {
					"valid_children" : [ "default", "folder", "file" ],
					"icon" : {
						"image" : "/static/smap/img/folder.png",
					},
				},
			}
		},
		"plugins" : [ "themes", "json_data", "ui", "dnd", "crrm", "types","hotkeys"],
		"ui": {"select_multiple_modifier" : "alt"},
    })
   .bind("dblclick.jstree", function(event) {
           var node = $(event.target).closest("li");
           if ($(node).hasClass("jstree-leaf")) {
             $("#__tree").jstree("select_node", node);
           } else {
             $("#__tree").jstree("toggle_node", node);
           }
         })
   .bind("move_node.jstree", function(event , data) {        
         //create paths to parse for setpoint analysis
         data.rslt.o.each(function(i){
         if ($.jstree._reference(data.rslt.op).get_path(data.rslt.op).slice(0,1) == 'CBE Toolkit'){
         	var toolkit = true;
         	var setpointPaths = $.jstree._reference(data.rslt.op).get_path(data.rslt.op)
         }
         else {var setpointPaths = $.jstree._reference(data.rslt.op).get_path(data.rslt.op).slice(1)}
         setpointPaths.push($.jstree._reference(data.rslt.o[i]).get_text(data.rslt.o[i]))
         setpointPaths = setpointPaths.join().replace(new RegExp(",", "g"),'/')
         if (setpointPaths.slice(0,1) != '/'){setpointPaths = '/' + setpointPaths}
         $.jstree._reference(data.rslt.o[i]).set_text(data.rslt.o[i], setpointPaths)
         if (!toolkit){$('#searchExpressionText').val(setpointPaths)}
        })
        })
   $('#treeSelections').show().append('<input type="hidden" id="aggregate">')
}

function saveSetpointTree(save){
	document.getElementById('projectId').value = sessvars.sessionObj['projectId']
	var treeJSON = $('#treeSelections').jstree("get_json");
	if (save){
		url = '/pmp/comfort/';
		$.ajax({
			type: "POST",
			url: url,
			data: JSON.stringify({'form': $('form#configFile').serializeObject(), 'treeJSON': treeJSON}),
			datatype: "json",
			success: function(data){
				var configFileName = $('select#id_for_name').find("option:selected").text()
	            //reload drop-down list if the name is new
	            if (configFileName != $('#id_form_name').val()){$('#setpointHeading').html(data)}
				$('#success').html("<strong>&nbsp;&nbsp;Saved successfully</strong>").fadeIn().delay(2000).fadeOut(1000);        
			}
		});
	}
	else {return treeJSON}	
}

function setpointAnalysis(wkd, sh, eh, ad) {
	var resample_s = $('#resampleTime').val();
	//paths_dict --key [setpoint] value temp

   	$.ajax({
		type: "POST",
		url: "/pmp/setpoint/",
		data: JSON.stringify({'paths_dict': paths_dict, 'start': global_start, 'end': global_end, 'resample_s': resample_s, 'sh': sh, 'eh':eh, 'ad':ad, 'wkd': wkd, 'projectId': sessvars.sessionObj['projectId']}),
		success: function(data){
		   	if (data.success){
		    	var hist_data = data.hist_data;
		    	diffData = data.diffData
				var N = hist_data.length
				//generate histogram data
				var histogram = d3.layout.histogram();
				histogram.bins(d3.scale.linear().domain([-10, 11]).ticks(21));
				bin_data = histogram(hist_data);
				var x = bin_data.map(function(d) {
					return d.x;
				});
				var y = bin_data.map(function(d) {
					return d.y;
				});
				var chartData = [];
				
				for(var i = 0; i < x.length; i++) {
					chartData.push([x[i], y[i] / hist_data.length * 100])
				}
				var chart_data = [{
				data : chartData,
				label: "n = " + N,
				bars : {
					show : true,
					barWidth : 0.9
				},
				}] 
				setpointChart(chart_data, x, N);
				$('#chartImage').show();
				$('#chartImageCheck').removeAttr("disabled") //don't know why/where it is getting set to disabled in the first place!
			}
			else {alert('No valid data for this time range.');}
			//unblock the blocking overlay
    		$('#chart').unblock();
    	},
    	error: function(e){
    		alert('Problem with your query. Check that you have valid points and setpoints defined.');
			//unblock the blocking overlay
    		$('#chart').unblock();
    	}
	});
}

function setpointChart(chart_data, x, N){
	$('#chart').attr('style', 'width:100%;height:450px')
	cleanChart();
	var options =  {
		colors : colormap,
		xaxes : [{
			ticks : x,
			tickDecimals : 0,
			tickLength : 5,
			axisLabelUseCanvas : true,
			axisLabelPadding: 15,
			axisLabel : 'Deviation from Setpoint (F)',
			axisLabelFontSizePixels: 11,
			axisLabelFontFamily: 'Lucida Sans'
		}],
		yaxes : [{
			position : 'left',
			axisLabelUseCanvas : true,
			axisLabelPadding: 10,
			axisLabel : 'Percent of Readings',
			axisLabelFontSizePixels: 11,
			axisLabelFontFamily: 'Lucida Sans'
		}],
		bars : {
			lineWidth : 0
		},
		legend : {show: true, position: "ne"},
		grid : {
			borderWidth : 0,
			clickable: true,
			hoverable : true,
			markings: [ { xaxis: { from: d3.min(x), to: d3.min(x) } }]
		}
	}
	plot = $.plot($("#chart"), chart_data, options);

    var previousPoint = null;
    $("#chart").bind("plothover", function (event, pos, item) {
    	if (item) {
        	if (previousPoint != item.dataIndex) {
                previousPoint = item.dataIndex;            
                    $("#tooltip").remove();
                    var x = item.datapoint[0].toFixed(2),
                        y = item.datapoint[1].toFixed(2);
                    showTooltip(item.pageX, item.pageY, y);
                }
            }
            else {
                $("#tooltip").remove();
                previousPoint = null;            
            }
    });
    var previousClickPoint = null;
    $("#chart").bind("plotclick", function (event, pos, item) {
        if (item) {
        	if (previousClickPoint != item) {
                if (previousClickPoint){
           			plot.unhighlight(previousClickPoint.series, previousClickPoint.datapoint);
                }
                $("#diffTable").remove();
                previousClickPoint = item; 
	            plot.highlight(item.series, item.datapoint);
	            var setpointHistX = Number(item.datapoint[0]);
	            var fpbHist = createDiffTable(diffData, setpointHistX);
	        }
	        else {
	        	$("#diffTable").remove();
	        	previousClickPoint = null;
	        }
        }
    });
}

function createDiffTable(diffData, setpointHistX){
	var su = smaputil
	var fpbHist = {};
	for (element in diffData){
		diffData[element].forEach(function(diff){
			if (diff >= setpointHistX && diff < setpointHistX + 1){
				if (!fpbHist[element]){fpbHist[element]=0};
				fpbHist[element]++;
			}
		});
	}
	var diffHTML = "<table class=\"table-striped\"><thead><tr><th>Stream:</th><th>Count</th></tr></thead>"
	function createLinks(index){
		if (index < Object.keys(fpbHist).length){
			var element = Object.keys(fpbHist)[index]
			var paths = [element, paths_dict[element]]
			smaputil.loadUuids(paths).done(function(uuid_dict){
				var fpb = element.split('/').length - 2
				var uuids = []
				for (path in uuid_dict){
					uuids.push(String(uuid_dict[path]))	
				}		
				diffHTML+= '<tr><td><a href=\"http://smap.cbe.berkeley.edu/pmp/trending/?streamids=' + String(uuids) + '&start=' + String(naive_start) + '&end=' + String(naive_end) + '&stack=false&tree=0&axes=1,1\" target=\"_blank\">' 
				+ element.split('/')[fpb] + "</a>:</td><td>" + fpbHist[element] + "</td></tr>"
				index++;
				createLinks(index);	
			})
			
		}
		else{
			diffHTML+= "</table>"
			$('#legend').html(diffHTML).fadeIn(200);
		}
	}
	createLinks(0)
}

function comfortZoneAnalysis(data){
    if (typeof data.success != 'undefined'){
		alert('No valid data for this time range. Make sure your start date falls on or after the beginning of your data (device instance start).')
    }
	else {
	    if ($('#ctRadioMapTop').is(':checked') || $('#ctRadioPlenumMap').is(':checked')){ //map type charts (mapTop and plenum analysis)
	    	cleanChart();
	    	$('#chartContainer').attr('class', 'span8')
	    	$('#chart').attr('style', '')
	    	$('#chart').html(data)
	    }
	    else if ($('#ctRadioTimeSeriesTop').is(':checked')){
	    	cleanChart();
	    	$('#chartContainer').attr('class', 'span8')
	    	y_title = 'Operative temperature (F)';
	    	chart1 = new Highcharts.Chart({
		         chart: {
		            renderTo: 'chart',
		            zoomType: 'xy',
		         },
		         title: {
		            text: ' '
		         },
		         xAxis: {
				   type: 'datetime',
		     	   title: {
		           text: ''
		            }
		         },
		         yAxis: {
		            title: {
		               text: y_title
		            },
		         },
		         plotOptions: {
		         	spline: {
	                marker: {
	                    enabled: false,
	                    states: {
	                        hover: {
	                            enabled: true,
	                        }
	                    }
	                },
	               }
	             },
		         credits: {enabled: false},
		         series: data.data,
		      });
	    }
	    else if ($('#ctRadioPlenumBoxplot').is(':checked')) {
	    	console.log('here')
	    	if (data.categories.length < 1){alert('No valid data for this time range.'); $('#chart').unblock(); return;}
			if (data.alert == true){alert('The time period you selected resulted in too many entries to display. Only the first 24 entries are shown.')}
			if (data.categories.length > 8){label_style = {rotation: -55, align: 'right'}}
			else {label_style = {}}
			chart1 = new Highcharts.Chart({
		         chart: {
		            renderTo: 'chart',
		            zoomType: 'xy',
		         },
		         title: {
		            text: ' '
		         },
		         xAxis: {
		           categories: data.categories,
		     	   labels: label_style,
		     	   title: {
		           text: ''
		            }
		         },
		         yAxis: {
		            title: {
		               text: 'Plenum temperature (F)'
		            },
		         },
		         credits: {enabled: false},
		         series: data.data,
		      });
	    }
	    else if ($('#ctRadioComfortTool').is(':checked')){
	    	new_page = window.open('','_blank','width=1100, height=900, scrollbars=1');
	    	new_page.document.open();
	    	new_page.document.write(data);
	    	new_page.document.close();
			new_page.focus();
	    }
    }
	$('#chart').unblock();
}

function stratificationChart(data, comfort){
	$('#chart').attr('style', 'width:100%;height:450px')
	if (data.data.length>0){
		cleanChart();
		if (data.alert){try{alert('The time range and resample rate combination you have selected resulted in too many series to be displayed properly. The results have been truncated.')} catch(err){}}
		var chart_data = []
		if (data['series_colors'].length > 0){
			for(var i=0; i<=data['data'].length; i++) {
				chart_data.push({
		    		color: data['series_colors'][i],
		    		data: data['data'][i],
			    	lines: {show: true},
			    	points: {show: true, symbol: data['symbols'][i], radius: 4},
			    	label: data['labels'][i]
			    });	
			}
		}
		else {
			for(var i=0; i<=data['data'].length; i++) {
				chart_data.push({
		    		data: data['data'][i],
			    	lines: {show: true},
			    	points: {show: true, symbol: data['symbols'][i], radius: 4},
			    	label: data['labels'][i]
			    });	
			}
		}
		if (comfort == false){
			var options = {
				colors : colormap,
				xaxes : [{
					axisLabelUseCanvas : true,
					axisLabelPadding: 15,
					axisLabel : 'Dry Bulb Temperature (F)',
					axisLabelFontSizePixels: 11,
					axisLabelFontFamily: 'Lucida Sans'
				}],
				yaxes : [{
					position : 'left',
					zoomRange: false,
					panRange: false,
					axisLabelUseCanvas : true,
					axisLabelPadding: 15,
					axisLabel : 'Height (in.)',
					axisLabelFontSizePixels: 11,
					axisLabelFontFamily: 'Lucida Sans'
				}],
				zoom: {interactive: true, amount: 1.2},
				pan: {interactive: true},
				legend: {
				    show: true,
				    position: "nw",
				    container: $('#legend')
			  	},
				grid : {
					borderWidth : 0,					
				}
			}
		}
		else {
			var options = {
				series: {
					points: {fill: .7, fillColor: false},
				},
				colors : colormap,
				xaxes : [{
					axisLabelUseCanvas : true,
					axisLabelPadding: 15,
					axisLabel : 'Average Occupied Zone Dry Bulb Temperature (F)',
					axisLabelFontSizePixels: 11,
					axisLabelFontFamily: 'Lucida Sans'
				}],
				yaxes : [{
					position : 'left',
					panRange: [-15, 15],
					axisLabelUseCanvas : true,
					axisLabelPadding: 15,
					axisLabel : 'Occupied Zone Stratification (F)',
					axisLabelFontSizePixels: 11,
					axisLabelFontFamily: 'Lucida Sans'
				}],
				zoom: {interactive: true, amount: 1.2},
				pan: {interactive: true},
				legend: {
				    show: true,
				    position: "nw",
				    container: $('#legend')
			  	},
				grid : {
					borderWidth : 0,
					markings: comfortZone,
				}
			}
		}
		plot = $.plot($("#chart"), chart_data, $.extend(true, {}, options, current_zoom));
	}
	else {alert('No valid data for this time range. Make sure your start date falls on or after the beginning of your data (device instance start).')}
	function comfortZone(){
		    var clo = $('#clo').val()
			var vel = 0.15 //at some point this should be the velocity from the ICM itself instead of hard-coded
			var met = $('#met').val()
			var comfort_limits = calcComfortLimits(clo, vel, met, true) //assumes rh=50%
			var x_low = CtoF(comfort_limits[1])
			var x_high = CtoF(comfort_limits[3])  
			var markings = [ { xaxis: { from: x_low, to: x_high }, yaxis: { from: 0, to: 5 }, color: "#fef2c6" }]
			return markings	
		}
	$('#chart').unblock()
}

function analysisPlot(maintain_zoom){
	$('#chartImageCheck').removeAttr("checked") //reset save image check
	$('#chartImageSave').hide();
	if (typeof maintain_zoom == 'undefined'){maintain_zoom = false}
	if (maintain_zoom){current_zoom = getCurrentZoom()}
	else {current_zoom = {}}
	//block chart overlay
	$('#chart').block({ 
		css: { 
			border: 'none', 
		    padding: '15px', 
            backgroundColor: '#002e48', 
            '-webkit-border-radius': '10px', 
            '-moz-border-radius': '10px', 
            opacity: .75, 
            color: '#fff' 
        }
    });
    
    //setup needed variables from input fields 
    var wkd = document.getElementById("wkdays").checked;
	var sh = Number(document.getElementById("startHour").value);
	var eh = Number(document.getElementById("endHour").value);
	var ad = document.getElementById("alldays").checked;
	
	//get start and end time in milliseconds since epoch UTC
	getTimeRange();

	var resample_s = $('#resampleTime').val();
	
	//if setpoint analysis, get the paths and run the analysis
	if (document.getElementById("analysisRadio1").checked){
		chart_engine = 'flot'
		//get json data
		treeJSON = saveSetpointTree();
		getSetpointPaths();
		setpointAnalysis(wkd, sh, eh, ad);
		return;
	}
	
	//send information to django after the tree selection function has completed
	//needs to be divided into analysis type
	treeSelection().done(function(treePaths){
		var filterSelections = treePaths
		filterSelections['start_time'] = global_start
		filterSelections['end_time'] = global_end
		filterSelections['wkd'] = wkd
		filterSelections['sh'] = sh
		filterSelections['eh'] = eh
		filterSelections['projectId'] = sessvars.sessionObj['projectId']
		filterSelections['resample_s'] = resample_s
		filterSelections['ad'] = ad
		
		//check to see what you are aggregating by
		if (!document.getElementById("analysisRadio5").checked && !document.getElementById("analysisRadio6").checked){
			if (document.getElementById("aggregate").checked){
				filterSelections['aggregate'] = $("input:radio[name=agg]:checked").val();
				}
		}
		
		//determine the specific chart type that is being requested
		if (document.getElementById("analysisRadio2").checked){
			if ($('#ctRadioMapTop').is(':checked')) {
				chart_engine = 'map'
				filterSelections['chart_type'] = 'map_top'
				filterSelections['floor'] = $('#id_floor').val()
			}
			else if ($('#ctRadioTimeSeriesTop').is(':checked')) {
				chart_engine = 'highcharts'
				filterSelections['chart_type'] = 'spline_top'
			}
			else if ($('#ctRadioComfortTool').is(':checked')) {
				chart_engine = 'ct'
				filterSelections['chart_type'] = 'comfort_tool'
				filterSelections['met'] = $('#met').val();
				filterSelections['clo'] = $('#clo').val();
			}
		}
		
		//handle performance summary model chart type options
		else if (document.getElementById("analysisRadio5").checked){
			chart_engine = 'highcharts'
			filterSelections['ieq_model'] = $('form#ieqModelForm').serializeObject()
			filterSelections['save_model'] = document.getElementById("saveIeqModel").checked;
			filterSelections['ieq_save'] = $('form#ieqSaveForm').serializeObject()
			filterSelections['met'] = $('#met').val();
			filterSelections['clo'] = $('#clo').val();
			if ($('#ctRadioStackedBar').is(':checked')){
				filterSelections['chart_type'] = 'bar'
			}
			else{
				filterSelections['chart_type'] = 'ieq_map'
				filterSelections['floor'] = $('#id_floor').val()
			}
		}
		
		//plenum analysis
		else if (document.getElementById("analysisRadio6").checked){
			if ($('#ctRadioPlenumMap').is(':checked')) {
				chart_engine = 'map'
				filterSelections['chart_type'] = 'plenum_map'
				filterSelections['floor'] = $('#id_floor').val()	
			}
			else {
				chart_engine = 'highcharts'
				if ($('#avgDay').is(':checked')){
					filterSelections['chart_type'] = 'boxplotAvgDay'
				}
				else{
					filterSelections['chart_type'] = 'boxplotLT'
				}
			}
			
		}
		
		filterSelections['analysisType'] = analysisType
		filterSelections['avg_day'] = document.getElementById("avgDay").checked;
		
		//finally determine strat_device type
		if (document.getElementById("analysisRadio3").checked || document.getElementById("analysisRadio4").checked){
			chart_engine = 'flot'
			if (document.getElementById('cartChk').checked && document.getElementById('fpChk').checked){var stratDevice = 'cart_pole'}
		    else if (document.getElementById('cartChk').checked){var stratDevice = 'Cart'}
		    else if (document.getElementById('fpChk').checked){var stratDevice = 'Fixed pole'}
		    else {var stratDevice = 'none'}
		    filterSelections['stratDevice'] = stratDevice
		 }
		else {filterSelections['stratDevice'] = 'none'}
		
		//send parameters to comfort def and run the appropriate analysis upon success 
		$.ajax({
			type: "POST",
			url: "/pmp/comfort/",
			data: JSON.stringify(filterSelections),
			datatype: "json",
			success: function(data){					
				if (document.getElementById("analysisRadio2").checked){comfortZoneAnalysis(data);}
				else if (document.getElementById("analysisRadio3").checked){stratificationChart(data, true);}
				else if (document.getElementById("analysisRadio4").checked){stratificationChart(data, false); document.getElementById('exportbutton').disabled = false;}
				else if (document.getElementById("analysisRadio5").checked){ieqModelChart(data);}
				else if (document.getElementById("analysisRadio6").checked){comfortZoneAnalysis(data);}
				$('#chartImage').show();
			}
		});
	})
	//check for proper form submittal
	if (document.getElementById("analysisRadio3").checked || document.getElementById("analysisRadio4").checked){
		if (!document.getElementById('cartChk').checked && !document.getElementById('fpChk').checked){
	    	return $('#analysisOptionsE').html('<p style="color: red; font-weight: bold">At least one device needs to be selected.</p>').show().delay(3000).fadeOut(2000)
	    }
   	}	
}

function showTooltip(x, y, contents) {
        $('<div id="tooltip">' + contents + '</div>').css( {
    position: 'absolute',
    display: 'none',
    font: '12px sans-serif',
    top: y - 20,
    left: x + 5,
    border: '1px solid #fdd',
    padding: '2px',
    'background-color': '#fee',
    opacity: 0.80
        }).appendTo("body").fadeIn(200);
}

function getSetpointPaths(){
	var temp_paths = []
	var setpt_paths = []
	paths_dict = {}
	if (typeof treeJSON[0].children != 'undefined'){
		for (var i=0; i<treeJSON[0].children.length; i++){
			var temp_arry = treeJSON[0].children[i].data.split('/')
			//if we are dealing with toolkit devices, need to look up the path from the database first
			if (temp_arry[1] == 'CBE Toolkit'){
				var p = temp_arry.slice(1)
				$.ajax({
					type: "POST",
					url: "/pmp/trending/",
					data: JSON.stringify({'path': p, 'projectId': sessvars.sessionObj['projectId']}),
					success: function(data){
						var stream_data = $.parseJSON(data['metadata'])
						temp_paths.push(stream_data[0].fields.path)
					},
					async: false
				})
			}
			else {temp_paths.push(treeJSON[0].children[i].data)}
		}
		if (typeof treeJSON[1] != 'undefined'){
			for (var i=0; i<treeJSON[1].children.length; i++){
				var setpt_arry = treeJSON[1].children[i].data.split('/')
				//if we are dealing with toolkit devices, need to look up the path from the database first
				if (setpt_arry[1] == 'CBE Toolkit'){
					var p = setpt_arry.slice(1)
					$.ajax({
						type: "POST",
						url: "/pmp/trending/",
						data: JSON.stringify({'path': p, 'projectId': sessvars.sessionObj['projectId']}),
						success: function(data){
							var stream_data = $.parseJSON(data['metadata'])
							setpt_paths.push(stream_data[0].fields.path)
						},
						async: false
					})
				}
				else {setpt_paths.push(treeJSON[1].children[i].data)}		
			}
			if (setpt_paths.length != temp_paths.length){
				alert('You need to have the same number of setpoint and temperature points')
				return false
			}
			//setup a dictionary of temp/setpt pairs for use later
			for (var i=0; i<temp_paths.length; i++){
				paths_dict[setpt_paths[i]] = temp_paths[i] 
			}
		}
		else if ($('#fixed_setpoints').is(':checked')){
			paths_dict['points'] = temp_paths;
			paths_dict['fixed'] = true;
		}
		else if ($('#custom_fixed_setpoints').is(':checked')){
			paths_dict['points'] = temp_paths;
			paths_dict['custom_fixed_low'] = $('#custom_setpoint_low').val()
			paths_dict['custom_fixed_high'] = $('#custom_setpoint_high').val()
		}
	}
}

function calcComfort(data, clo, vel, met){ 
    var x, to, rh, result1 = [], result2 = []
    var N = data.to.length      
	//console.log(data);
    for (var i = 0; i < N; i++){
        to = FtoC(data.to[i])
        rh = data.rh[i]
        x = comf.pmv(to, to, vel, rh, met, clo, 0)
        result1.push(x[0])
        result2.push(x[1])
    }
    return [result1, result2]
}

function calcComfortLimits(clo, vel, met, comfort){
    comfort = typeof comfort !== 'undefined' ? comfort : false;
    var fn = function(to){
        var x = comf.pmv(to, to, vel, rh, met, clo, 0);
        return x[0]        
    }
    var rh = 0 
    var upper_rh0 = psy.bisect(0,200,fn,0.01,0.5)
    var lower_rh0 = psy.bisect(0,200,fn,0.01,-0.5)
    rh = 100
    var upper_rh1 = psy.bisect(0,200,fn,0.01,0.5)
    var lower_rh1 = psy.bisect(0,200,fn,0.01,-0.5)
    //confusing to have named these variables rh...as they are really temps (C)
    if (comfort){
    	rh = 50
    	var upper_rh1 = psy.bisect(0,200,fn,0.01,0.5)
    	var lower_rh1 = psy.bisect(0,200,fn,0.01,-0.5)
    }
    
    return [lower_rh0, lower_rh1, upper_rh0, upper_rh1]
}

function cleanChart(){
	document.getElementById('exportbutton').disabled = true;
	$('#chartContainer').attr('class', 'span7')
	$('#chart').html('')
	$("#chart").unbind()
	$('#legend').html('')
	$('#legend').attr('style', "")
	$('#resampleTime').removeAttr('disabled')
	$('#resample_select').removeAttr('disabled')
}
